﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using Timer = System.Threading.Timer;

namespace CommunicationProtocol.dto
{
    public class StaticPlant : BaseObject
    {
        public short coolingTime { get; set; }

        protected Object coolingTimeLock = new object();


        private readonly short defaultCoolingTime;

        private string coolingTimeOwner;


        public StaticPlant(short objectId, byte objectType, byte locationX, byte locationY, short defaultCoolingTime) : base(
            objectId, objectType, locationX, locationY)
        {
            this.defaultCoolingTime = defaultCoolingTime;
           // new Timer();
        }

  

        public int getCoolingTime()
        {
            Monitor.Enter(coolingTimeLock);
            try
            {
                return coolingTime;
            }
            finally
            {
                Monitor.Exit(coolingTimeLock);
            }
        }

        /**
         * 如果冷却时间为0，则返回零，并重置冷却时间
         * 如果冷却时间不为0，则返回当前冷却剩余时间
         * 单位 毫秒
         */
        public int setOwnerIdIfCoolingTimeIsZero(string userId, out string currentOwnerId)
        {
            /*

             使用   Monitor   锁定对象（即引用类型）而不是值类型。
            将值类型变量传递给   Enter   时，它被装箱为对象。
            如果再次将相同的变量传递给   Enter，则它被装箱为一个单独对象，
            而且线程不会阻止。Monitor   本应保护的代码未受保护。
            此外，将变量传递给   Exit   时，也创建了另一个单独对象。
            因为传递给   Exit   的对象和传递给   Enter   的对象不同，Monitor   
            将引发   SynchronizationLockException
             */
            Monitor.Enter(coolingTimeLock);
            try
            {
                if (!(coolingTimeOwner is null))
                {
                    currentOwnerId = coolingTimeOwner;
                    return -1;
                }

                if (coolingTime == 0)
                {
                    currentOwnerId = coolingTimeOwner = userId;
                    return 0;
                }

                currentOwnerId = coolingTimeOwner;
                return coolingTime;
            }
            finally
            {
                Monitor.Exit(coolingTimeLock);
            }
        }

        /**
         * 重置 植物的冷却时间 和 植物的拥有者
         */
        public bool createAPlant(string currentUserId)
        {
            Monitor.Enter(coolingTimeLock);
            try
            {
                if (Equals(coolingTimeOwner, currentUserId))
                {
                    coolingTimeOwner = null;
                    //coolingTime = defaultCoolingTime;
                    return true;
                }

                return false;
            }
            finally
            {
                Monitor.Exit(coolingTimeLock);
            }
        }

        public void reduceCoolingTime(short millisecond)
        {
            Monitor.Enter(coolingTimeLock);
            try
            {
                coolingTime -= millisecond;
            }
            finally
            {
                Monitor.Exit(coolingTimeLock);
            }
        }
    }
}